package com.hb.config;

import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer;

/**
 * 1、扩展 AbstractAnnotationConfigDispatcherServletInitializer 的任意类都会自动地配置 DispatcherServlet 和 Spring 应用上下文（WebApplicationContext），
 * Spring 的应用上下文会位于应用程序的 Servlet 上下文之中（因为当 Web 应用集成 Spring 容器后，代表 Spring 容器的 WebApplicationContext 对象将以
 * WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE 为键存放在 ServletContext 的属性列表中。您当然可以直接通过以下语句获取 WebApplicationContext：
 * WebApplicationContext wac = (WebApplicationContext)servletContext.getAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE);
 * 但通过位于 org.springframework.web.context.support 包中的 WebApplicationContextUtils 工具类获取 WebApplicationContext 更方便：
 * ApplicationContext ac1 =WebApplicationContextUtils.getRequiredWebApplicationContext(ServletContext sc);
 * ApplicationContext ac2 =WebApplicationContextUtils.getWebApplicationContext(ServletContext sc);
 * ac1.getBean("beanId");
 * ac2.getBean("beanId");）。
 * 2、在 Servlet 3.0 环境中，容器会在类路径（默认就是部署项目的根路径）中查找实现 javax.servlet.ServletContainerInitializer 接口的类，如果能发现的话，就会用它来配置 Servlet 容器。
 * Spring 提供了这个接口的实现，名为 SpringServletContainerInitializer，这个类反过来又会查找实现 WebApplicationInitializer 接口的类并将配置的任务交给它们来完成。
 * 3、Spring 3.2 引入了一个便利的 WebApplicationInitializer 基础实现，也就是 AbstractAnnotationConfigDispatcherServletInitializer，因为我们的 SpittrWebAppInitializer
 * 扩展了 AbstractAnnotationConfigDispatcherServletInitializer（同时也就实现了 WebApplicationInitializer），因此当部署到 Servlet 3.0 容器中的时候，容器会自动发现它，
 * 并用它来配置 Servlet 上下文。
 * 4、需要注意的是，通过 AbstractAnnotationConfigDispatcherServletInitializer 来配置 DispatcherServlet 是传统 web.xml 方式的替代方案。如果你愿意的话，
 * 可以同时包含 web.xml 和 AbstractAnnotationConfigDispatcherServletInitializer，但这其实并没有必要。如果按照这种方式配置 DispatcherServlet，而不是使用 web.xml
 * 的话，那唯一问题在于它只能部署到支持 Servlet 3.0 的服务器中才能正常工作，如 Tomcat 7 或更高版本。Servlet 3.0 规范在 2009 年 12 月份就发布了，因此很有可能你会将应用部署
 * 到支持 Servlet 3.0 的Servlet容器之中。如果你还没有使用支持 Servlet 3.0 的服务器，那么在 AbstractAnnotationConfigDispatcherServletInitializer 子类中配置
 * DispatcherServlet 的方法就不适合你了。你别无选择，只能使用 web.xml 了。
 */
public class SpittrWebAppInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {
    /**
     * 此方法返回的带有 @Configuration 注解的类将会用来定义 ContextLoaderListener 应用上下文中的 bean，其实就是 Spring 应用上下文——WebApplicationContext
     *
     * @return
     */
    @Override
    protected Class<?>[] getRootConfigClasses() {
        return new Class[]{RootConfig.class};
    }

    /**
     * 此方法返回的带有 @Configuration 注解的类将会用来定义 DispatcherServlet 应用上下文中的 bean
     *
     * @return
     */
    @Override
    protected Class<?>[] getServletConfigClasses() {
        return new Class[]{WebConfig.class};
    }

    /**
     * 将一个或多个路径映射到 DispatcherServlet 上
     *
     * @return
     */
    @Override
    protected String[] getServletMappings() {
        // 将 DispatcherServlet 映射到 “/”，表示它会是应用的默认 Servlet，处理进入应用的所有请求
        return new String[]{"/"};
    }
}
